/*********************************************************************************
 * Software License Agreement (BSD License)
 * Copyright (c) 2012, Carlos D. Correa (info@ngraph.org)
 * All rights reserved.
 * 
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 * 
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 * 3. Neither the name of netzen nor the
 *    names of its contributors may be used to endorse or promote products
 *    derived from this software without specific prior written permission.
 * 
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 *  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *********************************************************************************/
#ifndef PROPERTY_H
#define PROPERTY_H

#include <string>
#include <stdio.h>
#include <stdlib.h>
using namespace std;

typedef enum {
  PROPERTY_UNKNOWN, // 0
  PROPERTY_BOOL,    // 1 bool
  PROPERTY_INT,     // 2 int
  PROPERTY_FLOAT,   // 3 float
  PROPERTY_SIGNED,  // 4 signed
  PROPERTY_VEC2,            // 5
  PROPERTY_VEC3,            // 6
  PROPERTY_STRING,          // 7 string
  PROPERTY_ORDINAL,			// 8 also a string
  PROPERTY_SELECTION,       // 9
  PROPERTY_MULTISELECTION   // 10
} PropType;

struct Interval {
	float start, end;
	Interval(float a, float b) {
		start = a;
		end = b;
	}
};

/*
class Property {
 protected:
  PropType type;
 public:
  Property() { type = PROPERTY_UNKNOWN; } 
  Property(PropType t) { type = t; } 
  PropType getType() { return type;}
  virtual ~Property() { } //printf("Property type %d.Destroy\n", type);}
  virtual string toString() { return ""; }
  virtual void parseString(string ) { };
};
	

class StringProperty:public Property {
 public:
  string value;
 StringProperty(const char* s): Property(PROPERTY_STRING) {
    this->value = string(s);
  }
 StringProperty(string  s): Property(PROPERTY_STRING) {
    this->value = s;
  }
  virtual void set(string s) { this->value = s;}
  virtual string toString() { return value; }
  virtual void parseString(string s) { this->value = s; }
};

class ListProperty:public StringProperty {
 public:
  string model;
 ListProperty(const char* s, const char *model = 0): StringProperty(s) {
    this->model = model? string(model): "none";
    this->type = PROPERTY_SELECTION;
  }
 ListProperty(string s, string model = "none"): StringProperty(s) {
    this->model = model;
    this->type = PROPERTY_SELECTION;
  }
  virtual string toString() { return value; }
  virtual void parseString(string s) { this->value = s; }
};

class OrdinalProperty:public ListProperty {
public:
	OrdinalProperty(const char* s, const char *model = 0): ListProperty(s,model) {
		this->type = PROPERTY_ORDINAL;
	}
	OrdinalProperty(string s, string model = "none"): ListProperty(s,model) {
		this->type = PROPERTY_ORDINAL;
	}
	virtual string toString() { return value; }
	virtual void parseString(string s) { this->value = s; }
};

class MultiListProperty:public StringProperty {
 public:
  string model;
 MultiListProperty(const char* s, const char *model = 0): StringProperty(s) {
    this->model = model? string(model): "none";
    this->type = PROPERTY_MULTISELECTION;
  }
 MultiListProperty(string s, string model = "none"): StringProperty(s) {
    this->model = model;
    this->type = PROPERTY_MULTISELECTION;
  }
  virtual string toString() { return value; }
  virtual void parseString(string s) { this->value = s; }
};

class BoolProperty:public Property {
public:
    bool value;
    BoolProperty(const char* s): Property(PROPERTY_BOOL) {
        string sInput = string(s);
        if(sInput=="true"){
            this->value = true;
        }
        else if(sInput=="false"){
            this->value = false;
        }
        //this->value = bool(s);
    }
    BoolProperty(bool v): Property(PROPERTY_BOOL) {
        this->value = v;
    }
    BoolProperty(BoolProperty &p): Property(PROPERTY_BOOL) {
        this->value = p.value;
    }
    virtual void set(bool value) { this->value = value; }
    virtual string toString() {
        return string(value? "true":"false");
    }
    virtual void parseString(string s) { this->value = (s=="true"); }
};

class IntProperty:public Property {
 public:
  int value;
 IntProperty(int v): Property(PROPERTY_INT) {
    this->value = v;
  }
  IntProperty(IntProperty &p): Property(PROPERTY_INT) {
    this->value = p.value;
  }
  void set(int value) { this->value = value;}
  virtual string toString() { 
    char str[200];
    sprintf(str, "%d", value);
    return string(str); 
  }
  virtual void parseString(string s) { this->value = atoi(s.c_str()); }
};

class FloatProperty:public Property {
 public:
  float value;
 FloatProperty(float v): Property(PROPERTY_FLOAT) {
    this->value = v;
  }
 FloatProperty(FloatProperty &p): Property(PROPERTY_FLOAT) {
    this->value = p.value;
  }
  void set(float value) { this->value = value;}
  virtual string toString() { 
    char str[200];
    sprintf(str, "%f", value);
    return string(str); 
  }
  virtual void parseString(string s) { this->value = atof(s.c_str()); }
};

class SignedFloatProperty:public FloatProperty {
 public:
 SignedFloatProperty(float v): FloatProperty(v) {
    type = PROPERTY_SIGNED;
  }
 SignedFloatProperty(SignedFloatProperty &p): FloatProperty(p.value) {
    type = PROPERTY_SIGNED;
  }
};

class Vec2Property: public Property {
 public:
  float vector[2];
  Vec2Property(float x, float y): Property(PROPERTY_VEC2) {
    vector[0] = x;
    vector[1] = y;
  }
  Vec2Property(float * v): Property(PROPERTY_VEC2) {
    vector[0] = v[0];
    vector[1] = v[1];
  }
  float operator[](int i) {
    return vector[i];
  }
  virtual string toString() { 
    char str[200];
    sprintf(str, "(%f,%f)", vector[0], vector[1]);
    return string(str); 
  }
  virtual void parseString(string s) { 
    sscanf(s.c_str(), "(%f,%f)", &(vector[0]), &(vector[1]));
  }
};

class Vec3Property: public Property {
 public:
  float vector[3];
  Vec3Property(float x, float y, float z): Property(PROPERTY_VEC3) {
    vector[0] = x;
    vector[1] = y;
    vector[2] = z;
  }
  Vec3Property(float *v): Property(PROPERTY_VEC3) {
    vector[0] = v[0];
    vector[1] = v[1];
    vector[2] = v[2];
  }
  float operator[](int i) {
    return vector[i];
  }
  virtual string toString() { 
    char str[200];
    sprintf(str, "(%f,%f,%f)", vector[0], vector[1], vector[2]);
    return string(str); 
  }
  virtual void parseString(string s) { 
    sscanf(s.c_str(), "(%f,%f,%f)", &(vector[0]), &(vector[1]), &(vector[2]));
  }
};
*/

#endif
